﻿using Compass.Wasm.Shared.Wms;
using Compass.Wpf.ApiServices.Wms;
using System.Collections.Generic;

namespace Compass.Wpf.ViewModels.Wms;

public class LocationsViewModel : NavigationViewModel
{
    #region ctor
    private readonly ILocationService _locationService;
    private readonly IPrintsService _printsService;
    public LocationsViewModel(IContainerProvider provider) : base(provider)
    {
        _locationService = provider.Resolve<ILocationService>();
        _printsService=provider.Resolve<IPrintsService>();

        LocationDto=new LocationDto();
        PrintLabelCommand = new DelegateCommand<string>(PrintLabel);
        BuildNameCommand = new DelegateCommand(BuildName);
        AddLocationCommand = new DelegateCommand(AddLocation);
        UpdateLocationCommand = new DelegateCommand<LocationDto>(UpdateLocation);
        DeleteLocationCommand = new DelegateCommand<LocationDto>(DeleteLocation);
        SaveLocationCommand = new DelegateCommand(SaveLocation);

        UpdateRoles = "admin,whse";
    }

    private string updateRoles;
    public string UpdateRoles
    {
        get => updateRoles;
        set { updateRoles = value; RaisePropertyChanged(); }
    }

    public DelegateCommand<string> PrintLabelCommand { get; }

    public DelegateCommand BuildNameCommand { get; }
    public DelegateCommand AddLocationCommand { get; }
    public DelegateCommand<LocationDto> UpdateLocationCommand { get; }
    public DelegateCommand<LocationDto> DeleteLocationCommand { get; }
    public DelegateCommand SaveLocationCommand { get; }
    #endregion

    #region 右侧展开栏属性
    private bool isRightDrawerOpen;
    /// <summary>
    /// 右侧窗口是否展开
    /// </summary>
    public bool IsRightDrawerOpen
    {
        get => isRightDrawerOpen;
        set { isRightDrawerOpen = value; RaisePropertyChanged(); }
    }
    private string rightDrawerTitle = null!;
    public string RightDrawerTitle
    {
        get => rightDrawerTitle;
        set { rightDrawerTitle = value; RaisePropertyChanged(); }
    }
    #endregion

    #region 属性
    private Warehouse_e warehouse;
    public Warehouse_e Warehouse
    {
        get => warehouse;
        set
        {
            SetProperty(ref warehouse, value);
            SearchAll = false;
        }
    }

    private string[] warehouses = null!;
    public string[] Warehouses
    {
        get => warehouses;
        set { warehouses = value; RaisePropertyChanged(); }
    }

    private Area_e area;
    public Area_e Area
    {
        get => area;
        set
        {
            SetProperty(ref area, value);
            SearchAll = false;
        }
    }

    private string[] areas = null!;
    public string[] Areas
    {
        get => areas;
        set { areas = value; RaisePropertyChanged(); }
    }

    private string column;
    public string Column
    {
        get => column;
        set
        {
            SetProperty(ref column, value);
            SearchAll = false;
        }
    }

    private string[] columns = null!;
    public string[] Columns
    {
        get => columns;
        set { columns = value; RaisePropertyChanged(); }
    }

    private string row;
    public string Row
    {
        get => row;
        set
        {
            SetProperty(ref row, value);
            SearchAll = false;
        }
    }

    private string[] rows = null!;
    public string[] Rows
    {
        get => rows;
        set { rows = value; RaisePropertyChanged(); }
    }

    private string[] serials = null!;
    public string[] Serials
    {
        get => serials;
        set { serials = value; RaisePropertyChanged(); }
    }

    private string search;
    /// <summary>
    /// 搜索条件属性
    /// </summary>
    public string Search
    {
        get => search;
        set
        {
            SetProperty(ref search, value);
            Filter();
        }
    }
    private bool searchAll;
    /// <summary>
    /// 全范围搜索
    /// </summary>
    public bool SearchAll
    {
        get => searchAll;
        set
        {
            SetProperty(ref searchAll, value);
            GetDataAsync();
        }
    }

    private LocationDto locationDto;
    public LocationDto LocationDto
    {
        get => locationDto;
        set { locationDto = value; RaisePropertyChanged(); }
    }
    public ObservableRangeCollection<LocationDto> LocationDtos { get; } = new();
    public ObservableRangeCollection<LocationDto> FilterLocationDtos { get; } = new();

    private bool isEnable;
    public bool IsEnable
    {
        get => isEnable;
        set { isEnable = value; RaisePropertyChanged(); }
    }
    public bool? IsAllItemsSelected
    {
        get
        {
            var selected = FilterLocationDtos.Select(item => item.IsSelected).Distinct().ToList();
            return selected.Count == 1 ? selected.Single() : null;
        }
        set
        {
            if (value.HasValue)
            {
                SelectAll(value.Value, FilterLocationDtos);
                RaisePropertyChanged();
            }
        }
    }
    private static void SelectAll(bool select, IEnumerable<LocationDto> items)
    {
        foreach (var item in items)
        {
            item.IsSelected = select;
        }
    }
    #endregion

    #region 增删改查
    private void BuildName()
    {
        LocationDto.Name = $"{LocationDto.Warehouse}-{LocationDto.Area}{LocationDto.Column}-{LocationDto.Row}-{LocationDto.Serial}";
        var warehouseName = LocationDto.Warehouse switch
        {
            Warehouse_e.FSR or Warehouse_e.MEIR => "原料仓",
            Warehouse_e.FSS or Warehouse_e.MEIS => "板材仓",
            Warehouse_e.FST or Warehouse_e.MEIT => "周转仓",
            Warehouse_e.FSP or Warehouse_e.MEIP => "产线仓",
            Warehouse_e.FSF or Warehouse_e.FEIF => "成品仓",
            _ => string.Empty,
        };
        LocationDto.Remarks = $"{warehouseName}-{LocationDto.Area}{LocationDto.Column}区{LocationDto.Row}层-";
    }
    private void AddLocation()
    {
        LocationDto=new LocationDto();

        IsRightDrawerOpen = true;
        RightDrawerTitle = "添加库位";
    }

    private void UpdateLocation(LocationDto obj)
    {
        LocationDto=obj;
        var split = LocationDto.Name.Split('-');
        LocationDto.Column = split[1][1..];
        LocationDto.Row = split[2];
        LocationDto.Serial = split[3];

        IsRightDrawerOpen = true;
        RightDrawerTitle = "修改库位";
    }

    private async void DeleteLocation(LocationDto obj)
    {
        //删除询问
        var dialogResult = await DialogHost.Question("删除确认", $"确认删除库位：{obj.Name}, {obj.Remarks} 吗?");
        if (dialogResult.Result != ButtonResult.OK) return;
        await _locationService.DeleteAsync(obj.Id.Value);
        GetDataAsync();
    }

    private async void SaveLocation()
    {
        //数据验证
        if (string.IsNullOrWhiteSpace(LocationDto.Name))
        {
            //发送提示
            Aggregator.SendMessage("库位编号不能为空，请点击生成库位编号");
            return;
        }

        try
        {
            if (LocationDto.Id != null && LocationDto.Id.Value != Guid.Empty)
            {
                LocationDto.Name =LocationDto.Name.ToUpper();
                await _locationService.UpdateAsync(LocationDto.Id.Value, LocationDto);
                Aggregator.SendMessage($"库位：{LocationDto.Name}修改成功！");
                LocationDto.Id=Guid.Empty;
            }
            else
            {
                LocationDto.Name =LocationDto.Name.ToUpper();
                var dto = await _locationService.GetSingleByNameAsync(LocationDto.Name);
                if (dto.Status)
                {
                    Aggregator.SendMessage($"请不要重复添加，库位：{LocationDto.Name}！");
                    return;
                }
                await _locationService.AddAsync(LocationDto);
                Aggregator.SendMessage($"库位：{LocationDto.Name}添加成功！");
                LocationDto.Id=Guid.Empty;
            }
            IsRightDrawerOpen = false;
            GetDataAsync();
        }
        catch (Exception e)
        {
            //发送错误报告
            Aggregator.SendMessage(e.Message);
        }
    }

    #endregion

    #region 打印库位标签
    private async void PrintLabel(string type)
    {
        IsEnable = false;
        //打印询问
        var dialogResult = await DialogHost.Question("打印确认", "确认要打印标签吗?");
        if (dialogResult.Result != ButtonResult.OK)
        {
            IsEnable = true;
            return;
        }
        await Task.Delay(500);//防止卡屏

        //获取勾选的Item，并筛选托盘
        var selectItemDtos = FilterLocationDtos.Where(x => x.IsSelected).ToList();
        if (selectItemDtos.Count == 0)
        {
            Aggregator.SendMessage("请勾选（或全选）要打印的库位行！");
            IsEnable = true;
            return;
        }

        if (type.Equals("Location",StringComparison.OrdinalIgnoreCase))
        {
            await _printsService.PrintLocationLabelAsync(selectItemDtos);
        }
        else
        {
            //Cargo
            await _printsService.PrintCargoLabelAsync(selectItemDtos);
        }

        Aggregator.SendMessage("打印标签完成！");
        IsEnable = true;
    }

    #endregion

    #region 筛选
    private void Filter()
    {
        FilterLocationDtos.ReplaceRange(
            LocationDtos.Where(x =>
                string.IsNullOrEmpty(Search)||
                x.Name.Contains(Search, StringComparison.OrdinalIgnoreCase)||
                (!string.IsNullOrEmpty(x.Remarks)&&x.Remarks!.Contains(Search, StringComparison.OrdinalIgnoreCase))||
                (!string.IsNullOrEmpty(x.MtlNumber)&&x.MtlNumber!.Contains(Search, StringComparison.OrdinalIgnoreCase))||
                (!string.IsNullOrEmpty(x.Description)&&x.Description!.Contains(Search, StringComparison.OrdinalIgnoreCase))
            ));
        //有的时候Remarks是null，导致调用Contains报错

        //绑定勾选数据变更
        foreach (var item in FilterLocationDtos)
        {
            item.PropertyChanged += (sender, args) =>
            {
                if (args.PropertyName == nameof(ModuleDto.IsSelected))
                    RaisePropertyChanged(nameof(IsAllItemsSelected));
            };
        }
        IsAllItemsSelected = false;
    }
    #endregion

    #region 导航和初始化
    private void GetEnumNames()
    {
        //初始化一些枚举值
        Warehouses=Enum.GetNames(typeof(Warehouse_e));
        Areas=Enum.GetNames(typeof(Area_e));
        Columns = Enumerable.Range(1, 9).ToArray().ToList().ConvertAll<string>(x => x.ToString()).ToArray();
        
        Rows = Enumerable.Range(1, 9).ToArray().ToList().ConvertAll<string>(x => x.ToString()).ToArray();
        Serials=Enumerable.Range(1, 20).ToArray().ToList().ConvertAll<string>(x => x.ToString("00")).ToArray();

        Column = Columns[0];
        Row = Rows[0];
    }

    private async void GetDataAsync()
    {
        if (SearchAll)
        {
            var result = await _locationService.GetAllAsync();
            if (result.Status)
            {
                LocationDtos.ReplaceRange(result.Result);
            }
        }
        else
        {
            var ranks = $"{Column}-{Row}-";
            var result = await _locationService.GetAllByAreaAsync(Warehouse,Area,ranks);
            if (result.Status)
            {
                LocationDtos.ReplaceRange(result.Result);
            }
        }
        Filter();
    }

    public override void OnNavigatedTo(NavigationContext navigationContext)
    {
        base.OnNavigatedTo(navigationContext);

        GetEnumNames();
        GetDataAsync();
    }
    #endregion

}